﻿using System;
using System.Linq.Expressions;
using DapperLambdaSQL.Model;
using DapperLambdaSQL.Model.Exceptions;

namespace DapperLambdaSQL.Utils
{
    public static class DapperContextExtensions
    {
        /// <summary>
        /// SELECT 字句
        /// </summary>
        /// <typeparam name="T">数据库模型类型</typeparam>
        /// <param name="context">访问数据库对象</param>
        /// <returns>SELECT * FROM 表名</returns>
        public static DapperContext<T> Select<T>(this DapperContext<T> context) where T : DbModel
        {
            context.SqlString.SetSubject(context.SqlBuilder.Select<T>());
            return context;
        }

        /// <summary>
        /// SELECT 字句
        /// </summary>
        /// <typeparam name="T">数据库模型类型</typeparam>
        /// <param name="context">访问数据库对象</param>
        /// <param name="expression">查询字段表达式 eg:x =&gt; x.Id / x =&gt; new { x.Id, x.Name, ...}</param>
        /// <returns>SELECT filed1,filed2,... FROM 表名</returns>
        public static DapperContext<T> Select<T, TElement>(this DapperContext<T> context, Expression<Func<T, TElement>> expression) where T : DbModel
        {
            context.SqlString.SetSubject(context.SqlBuilder.Select(expression));
            return context;
        }

        /// <summary>
        /// WHERE 字句
        /// </summary>
        /// <typeparam name="T">数据库模型类型</typeparam>
        /// <param name="context">访问数据库对象</param>
        /// <param name="expression">条件字段表达式 eg:x =&gt; x.Id</param>
        /// <returns>WHERE field = @field</returns>
        public static DapperContext<T> Where<T, TElement>(this DapperContext<T> context, Expression<Func<T, TElement>> expression, SQLOperator sqlOperator) where T : DbModel
        {
            if (context.SqlString.Where?.IndexOf(SqlKeyWord.Where.Trim()) >= 0)
            {
                throw new BuildSQLException("SQL语句已存在WHERE关键字,考虑使用 And 或者 Or!");
            }

            context.SqlString.Where = $"{SqlKeyWord.Where}{ context.SqlBuilder.Where(expression, sqlOperator)}";
            return context;
        }

        /// <summary>
        /// AND 字句
        /// </summary>
        /// <typeparam name="T">数据库模型类型</typeparam>
        /// <param name="context">访问数据库对象</param>
        /// <param name="expression">条件字段表达式 eg:x =&gt; SqlWhere.Where(x.Name, SqlOperator.Equal)</param>
        /// <returns>AND field = @field</returns>
        public static DapperContext<T> And<T, TElement>(this DapperContext<T> context, Expression<Func<T, TElement>> expression, SQLOperator sqlOperator) where T : DbModel
        {
            if (context.SqlString.Where?.IndexOf(SqlKeyWord.Where.Trim()) < 0)
            {
                throw new BuildSQLException("SQL语句存在不存在WHERE关键字,请先使用 Where");
            }
            context.SqlString.Where += $"{SqlKeyWord.And}{ context.SqlBuilder.Where(expression, sqlOperator)}";
            return context;
        }
    }
}